package github.sf.mod.calculate.entity;


import github.sf.mod.calculate.Op;

import java.math.BigDecimal;

/**
 * 解释器
 */
public class Interpreter implements AstVisitor {
    @Override
    public Object visit(AstNode astNode, Object additional) {
        if (astNode instanceof Binary) {
            return visitBinary((Binary) astNode, additional);
        } else if (astNode instanceof NumberLiteral) {
            return visitNumberLiteral((NumberLiteral) astNode, additional);
        }
        return null;
    }

    @Override
    public Object visitBinary(Binary astNode, Object additional) {
        Object ret = null;
        Object v1 = this.visit(astNode.getExp1(), additional);
        Object v2 = this.visit(astNode.getExp2(), additional);
        Op op = astNode.getOp();
        switch (op) {
            case Plus:
                if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) {
                    ret = ((BigDecimal) v1).add((BigDecimal) v2);
                }
                break;
            case Minus:
                if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) {
                    ret = ((BigDecimal) v1).subtract((BigDecimal) v2);
                }
                break;
            case Multiply:
                if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) {
                    ret = ((BigDecimal) v1).multiply((BigDecimal) v2);
                }
                break;
            case Divide:
                if (v1 instanceof BigDecimal && v2 instanceof BigDecimal) {
                    ret = ((BigDecimal) v1).divide((BigDecimal) v2, 8, BigDecimal.ROUND_HALF_EVEN);
                }
                break;
            default:
                ret = BigDecimal.ZERO;
                break;
        }
        return ret;
    }

    @Override
    public Object visitNumberLiteral(NumberLiteral astNode, Object additional) {
        return astNode.getValue();
    }

    @Override
    public void dump(int index) {

    }
}
